﻿using System;
using System.Diagnostics;

namespace Simp.Model.CoreExpressions
{
	/// <summary>Encapsulates the negative expression, transforming a numeric into its negation.</summary>
	[ExpressionName(NegativeExpressionName)]
	[ParameterPolicy(1)]
	[DebuggerDisplay("{ExpressionHelper.Serialize(this)}")]
	public class NegativerExpression : IExpression, ISimplifiableExpression, IExpressionSerializer
	{
		/// <summary>Name of the expression.</summary>
		public const string NegativeExpressionName = "Negative";

		#region ISimplifiableExpression Members
		IExpression ISimplifiableExpression.Simplify(SimplificationMode simplificationMode, params IExpression[] parameterList)
		{
			if (parameterList == null)
			{
				throw new ArgumentNullException("parameterList");
			}
			if (parameterList.Length == 1)
			{
				IExpression innerExpression = parameterList[0];
				INumericExpression numericExpression = innerExpression as INumericExpression;

				if (numericExpression != null)
				{
					IntegerExpression integerExpression = numericExpression.GetInteger();
					RationalExpression rationalExpression = numericExpression.GetRational();
					RealExpression realExpression =
						numericExpression.GetReal(simplificationMode == SimplificationMode.AllowApproximation);

					if (integerExpression != null)
					{
						return new IntegerExpression(-integerExpression.Value);
					}
					else if (rationalExpression != null)
					{
						return RationalExpression.GetRational(-rationalExpression.Numerator, rationalExpression.Denominator);
					}
					else if (realExpression != null)
					{
						return new RealExpression(-realExpression.Value);
					}
					else
					{
						return null;
					}
				}
			}

			return null;
		}
		#endregion

		#region IExpressionSerializer Members
		void IExpressionSerializer.Serialize(AppendOnlyStringBuilder builder, params IExpression[] parameters)
		{
			if (builder == null)
			{
				throw new ArgumentNullException("builder");
			}
			if (parameters == null)
			{
				throw new ArgumentNullException("parameters");
			}
			if (parameters.Length != 1)
			{
				ExpressionHelper.SerializeGeneric(builder, this, parameters);
			}
			else
			{
				builder.Append("-");
				ExpressionHelper.Serialize(builder, parameters[0]);
			}
		}
		#endregion
	}
}